\subsection{Краткое введение в CPU}

\ac{CPU} это устройство исполняющее все программы.

\textbf{Немного терминологии:}

\begin{description}
\item[Инструкция]: примитивная команда \ac{CPU}.
Простейшие примеры: перемещение между регистрами, работа с памятью, примитивные арифметические операции.
Как правило, каждый \ac{CPU} имеет свой набор инструкций (\ac{ISA}).

\item[Машинный код]: код понимаемый \ac{CPU}. 
Каждая инструкция обычно кодируется несколькими байтами.
\item[Язык ассемблера]: машинный код плюс некоторые расширения, призванные облегчить труд программиста: макросы, имена, итд.
\item[Регистр CPU]: Каждый \ac{CPU} имеет некоторый фиксированный набор регистров общего назначения (\ac{GPR}).
$\approx 8$ в x86, $\approx 16$ в x86-64, $\approx 16$ в ARM.
Проще всего понимать регистр как временную переменную без типа.
Можно представить, что вы пишете на \ac{PL} высокого уровня и у вас только 8 переменных шириной 32 (или 64) бита.
Можно сделать очень много используя только их!
\end{description}

% TODO1 add about linker: "компоновщик" и "редактор связей" в русскоязычной лит-ре

Откуда взялась разница между машинным кодом и \ac{PL} высокого уровня?  Ответ в том, что люди и \ac{CPU}-ы отличаются друг от друга ---
человеку проще писать на \ac{PL} высокого уровня вроде \CCpp, Java, Python, а \ac{CPU} проще работать с абстракциями куда более низкого уровня.
Возможно, можно было бы придумать \ac{CPU} исполняющий код \ac{PL} высокого уровня, но он был бы значительно сложнее, чем те, что мы имеем сегодня.
И наоборот, человеку очень неудобно писать на ассемблере из-за его низкоуровневости, к тому же, крайне трудно обойтись без мелких ошибок.
Программа, переводящая код из \ac{PL} высокого уровня в ассемблер называется \IT{компилятором}
\footnote{В более старой русскоязычной литературе также часто встречается термин \q{транслятор}.}.

\myindex{ARM!\ARMMode}%
\myindex{ARM!\ThumbMode}%
\myindex{ARM!\ThumbTwoMode}%

\subsubsection{Несколько слов о разнице между \ac{ISA}}
x86 всегда был архитектурой с инструкциями переменной длины, так что когда пришла 64-битная эра, расширения x64 не очень сильно повлияли на \ac{ISA}.
ARM это \ac{RISC}-процессор разработанный с учетом инструкций одинаковой длины, что было некоторым преимуществом в прошлом.
Так что в самом начале все инструкции ARM кодировались 4-мя байтами%
\footnote{
Кстати, инструкции фиксированного размера удобны тем, что всегда можно легко узнать адрес 
следующей (или предыдущей) инструкции. Эта особенность будет рассмотрена в секции об операторе switch()~(\myref{sec:SwitchARMLot}).
}.
Это то, что сейчас называется \q{режим ARM}.
Потом они подумали, что это не очень экономично.
На самом деле, самые используемые инструкции\footnote{А это MOV/PUSH/CALL/Jcc} процессора на практике могут быть закодированы c использованием меньшего количества информации.
Так что они добавили другую \ac{ISA} с названием Thumb, где каждая инструкция кодируется всего лишь 2-мя байтами.
Теперь это называется \q{режим Thumb}.
Но не все инструкции ARM могут быть закодированы в двух байтах, так что набор инструкций Thumb ограниченный.
Код, скомпилированный для режима ARM и Thumb может сосуществовать в одной программе.
Затем создатели ARM решили, что Thumb можно расширить: так появился Thumb-2 (в ARMv7).
Thumb-2 это всё ещё двухбайтные инструкции, но некоторые новые инструкции имеют длину 4 байта.
Распространено заблуждение, что Thumb-2 --- это смесь ARM и Thumb. Это не верно. Режим Thumb-2 был дополнен до
более полной поддержки возможностей процессора и теперь может легко конкурировать с режимом ARM.
Основное количество приложений для \idevices скомпилировано для набора инструкций Thumb-2, потому что Xcode
делает так по умолчанию.
Потом появился 64-битный ARM. Это \ac{ISA} снова с 4-байтными инструкциями, без дополнительного режима Thumb.
Но 64-битные требования повлияли на \ac{ISA}, так что теперь у нас 3 набора инструкций ARM: режим ARM, режим Thumb (включая Thumb-2) и ARM64.
Эти наборы инструкций частично пересекаются, но можно сказать, это скорее разные наборы, нежели вариации одного.
Следовательно, в этой книге постараемся добавлять фрагменты кода на всех трех ARM \ac{ISA}.
\myindex{PowerPC}%
\myindex{MIPS}%
\myindex{Alpha AXP}%
Существует ещё много \ac{RISC} \ac{ISA} с инструкциями фиксированной 32-битной длины~--- это как минимум MIPS, PowerPC и Alpha AXP.
